<!DOCTYPE html>
<html  lang="zh-CN" >
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="theme-color" content="#fff" id="theme-color">
  <meta name="description" content="深山磨柴斧，一鸣震江湖">
  <link rel="icon" href="/img/ic_head.jpg">
  <title>014-Android自定义View(9)：事件分发&处理详解(图文)</title>
  
  
  <meta property="og:title" content="014-Android自定义View(9)：事件分发&amp;处理详解(图文)">
  
  
  <meta property="og:url" content="http://example.com/2019/07/17/014-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(9)%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91&amp;%E5%A4%84%E7%90%86%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/index.html">
  
  
  <meta property="og:img" content="/img/ic_head.jpg">
  
  
  <meta property="og:img" content="深山磨柴斧，一鸣震江湖">
  
  
  <meta property="og:type" content="article">
  <meta property="og:article:published_time" content="2019-07-17">
  <meta property="og:article:modified_time" content="2021-04-14">
  <meta property="og:article:author" content="Cupster">
  
  
  <meta property="og:article:tag" content="Android">
  
  <meta property="og:article:tag" content="Android自定义View">
  
  <meta property="og:article:tag" content="Android事件">
  
  
  
  
  <script>
    // control reverse button
    var reverseDarkList = {
      dark: 'light',
      light: 'dark'
    };
    var themeColor = {
      dark: '#1c1c1e',
      light: '#fff'
    }
    // get the data of css prefers-color-scheme
    var getCssMediaQuery = function() {
      return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    };
    // reverse current darkmode setting function
    var reverseDarkModeSetting = function() {
      var setting = localStorage.getItem('user-color-scheme');
      if(reverseDarkList[setting]) {
        setting = reverseDarkList[setting];
      } else if(setting === null) {
        setting = reverseDarkList[getCssMediaQuery()];
      } else {
        return;
      }
      localStorage.setItem('user-color-scheme', setting);
      return setting;
    };
    // apply current darkmode setting
    var setDarkmode = function(mode) {
      var setting = mode || localStorage.getItem('user-color-scheme');
      if(setting === getCssMediaQuery()) {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[setting];
      } else if(reverseDarkList[setting]) {
        document.documentElement.setAttribute('data-user-color-scheme', setting);
        document.getElementById('theme-color').content = themeColor[setting];
      } else {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[getCssMediaQuery()];
      }
    };
    setDarkmode();
  </script>
  <script>
    function loadScript(url, cb) {
      var script = document.createElement('script');
      script.src = url;
      if (cb) script.onload = cb;
      script.async = true;
      document.body.appendChild(script);
    }
  </script>
  
  <link rel="preload" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css" as="style" >
  <link rel="preload" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css" as="style" >
  
  <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.js" as="script">
  <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.css" as="style" >
  
  
  <link rel="preload" href="/js/lib/lozad.min.js" as="script">
  
  
  
  
  
  
  
  
<link rel="stylesheet" href="/css/main.css">

  
  
<link rel="stylesheet" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css">

  
  
<link rel="stylesheet" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css">

  
  
<link rel="stylesheet" href="/js/lib/lightbox/baguetteBox.min.css">

  
  
  
  
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <div class="wrapper">
    
    <nav class="navbar">
  <div class="navbar-logo">
    <span class="navbar-logo-main">
      
      <img class="navbar-logo-img" src="/img/ic_head.jpg" alt="logo">
      
      <span class="navbar-logo-dsc">不负明天</span>
    </span>
  </div>
  <div class="navbar-menu">
    
    <a href="/" class="navbar-menu-item">
    
    首页
    
    </a>
    
    <a href="/archives" class="navbar-menu-item">
    
    归档
    
    </a>
    
    <a href="/tags" class="navbar-menu-item">
    
    标签
    
    </a>
    
    <a href="/categories" class="navbar-menu-item">
    
    分类
    
    </a>
    
    <a href="/about" class="navbar-menu-item">
    
    关于
    
    </a>
    
    <a href="/links" class="navbar-menu-item">
    
    友链
    
    </a>
    
    <a class="navbar-menu-item darknavbar" id="dark"><i class="iconfont icon-weather"></i></a>
    <a class="navbar-menu-item searchnavbar" id="search"><i class="iconfont icon-search" style="font-size: 1.2rem; font-weight: 400;"></i></a>
  </div>
</nav>
    
    <div id="local-search" style="display: none;">
      <input class="navbar-menu-item" id="search-input" placeholder="请输入搜索内容...">
      <div id="search-content"></div>
    </div>
    
    <div class="section-wrap">
      <div class="container">
        <div class="columns">
          <main class="main-column">
<article class="card card-content">
  <header>
    <h1 class="post-title">
      014-Android自定义View(9)：事件分发&处理详解(图文)
    </h1>
  </header>
  <div class="post-meta post-show-meta">
    <time datetime="2019-07-17T04:23:37.000Z">
      <i class="iconfont icon-calendar" style="margin-right: 2px;"></i>
      <span>2019-07-17</span>
    </time>
    
    <span class="dot"></span>
    
    <a href="/categories/Android/" class="post-meta-link">Android</a>
    
    
    
    <span class="dot"></span>
    <span>2.1k 字</span>
    
  </div>
  
  <div class="post-meta post-show-meta" style="margin-top: -10px;">
    <div style="display: flex; align-items: center;">
      <i class="iconfont icon-biaoqian" style="margin-right: 2px; font-size: 1.15rem;"></i>
      
      
        <a href="/tags/Android/" class="post-meta-link">Android</a>
      
      
      <span class="dot"></span>
      
        <a href="/tags/Android自定义View/" class="post-meta-link">Android自定义View</a>
      
      
      <span class="dot"></span>
      
        <a href="/tags/Android事件/" class="post-meta-link">Android事件</a>
      
    </div>
  </div>
  
  </header>
  <div id="section" class="post-content">
    <p><a target="_blank" rel="noopener" href="https://blog.csdn.net/Cupster/article/details/112900623">【5年Android从零复盘系列之十四】Android自定义View(9)：事件分发&amp;处理</a></p>
<hr/>
# 1.三个重要方法

<p>三者关系伪代码</p>
<pre class="highlight"><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dispatchTouchEvent</span><span class="params">(MotionEvent event)</span></span>&#123;</span><br><span class="line">    <span class="keyword">boolean</span> consume = <span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">if</span>( onInterceptTouchEvent(event) )&#123;</span><br><span class="line">        consume = onTouchEvent(event);</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        consume = child.dispatchTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> consume;</span><br><span class="line">&#125;</span><br></pre>

<h2 id="1-1-事件分发：dispatchTouchEvent-MotionEvent-event"><a href="#1-1-事件分发：dispatchTouchEvent-MotionEvent-event" class="headerlink" title="1.1 事件分发：dispatchTouchEvent(MotionEvent event)"></a>1.1 事件分发：dispatchTouchEvent(MotionEvent event)</h2><p>用来进行事件分发；</p>
<p><strong>返回值表示是否下分发本次事件【默认的返回值子view的dispatchTouchEvent()的返回值】</strong></p>
<h2 id="1-2-事件拦截：onInterceptTouchEvent-MotionEvent-event"><a href="#1-2-事件拦截：onInterceptTouchEvent-MotionEvent-event" class="headerlink" title="1.2 事件拦截：onInterceptTouchEvent(MotionEvent event)"></a>1.2 事件拦截：onInterceptTouchEvent(MotionEvent event)</h2><p>用于判断是否拦截某个事件序列；</p>
<p><strong>返回值表示是否拦截本次事件【默认false】</strong></p>
<h2 id="1-3-事件处理：onTouchEvent-MotionEvent-event"><a href="#1-3-事件处理：onTouchEvent-MotionEvent-event" class="headerlink" title="1.3 事件处理：onTouchEvent(MotionEvent event)"></a>1.3 事件处理：onTouchEvent(MotionEvent event)</h2><p>用于处理事件；</p>
<p><strong>返回值表示是否消耗本次事件【默认true】</strong></p>
<p>如果不消耗，则同一事件序列，当前View无法再次接收到事件event，即该情况下不再被调用</p>
<h1 id="2-特殊情况"><a href="#2-特殊情况" class="headerlink" title="2.特殊情况"></a>2.特殊情况</h1><ol>
<li>当前View如果设置了OnTouchListener,事件分发当前View时，OnTouchListener的【onTouch()】方法会被先调用。</li>
</ol>
<ol start="2">
<li>如果OnTouchListener的【onTouch()】返回值为false,那么会继续调用「onTouchEvent()」；反之return true，则不会调用「onTouchEvent()」；</li>
</ol>
<ol start="3">
<li>在「onTouchEvent()」中，如果View设置了OnClickListener，则其中的[onClick()]会被最后调用，该方法优先级最低，事件传递的末端。</li>
</ol>
<h1 id="3-事件分发-amp-处理流程图"><a href="#3-事件分发-amp-处理流程图" class="headerlink" title="3.事件分发&amp;处理流程图"></a>3.事件分发&amp;处理流程图</h1><pre class="highlight"><span class="line">graph TD</span><br><span class="line">Z(activity.dispatchTouchEvent) --&gt; A(ViewGroupA.dispatchTouchEvent)</span><br><span class="line">A --&gt; B(ViewGroupA.onInterceptTouchEvent)</span><br><span class="line">B --&gt; C&#123;其返回值是否拦截&#125;</span><br><span class="line">C --&gt; | true:拦截 | D(ViewGroupA.onTouchEvent)</span><br><span class="line">C --&gt; | 默认false:不拦截 | E(ViewGroupB.dispatchTouchEvent)</span><br><span class="line">E --&gt; F(ViewGroupB.onInterceptTouchEvent)</span><br><span class="line">F --&gt; H&#123;其返回值是否拦截&#125;</span><br><span class="line">H --&gt; | true:拦截 | I(ViewGroupB.onTouchEvent)</span><br><span class="line">H --&gt; | 默认false:不拦截 | J(ViewC.dispatchTouchEvent)</span><br><span class="line">J --&gt;  K&#123;ViewC是否设置onTouchListener &#125;</span><br><span class="line">K --&gt; | 没有 | M(ViewC.onTouchEvent)</span><br><span class="line">K --&gt; | 有 | L&#123;ViewC.onTouchListener.onTouch&#125;</span><br><span class="line">L --&gt; | 默认false | M</span><br><span class="line">L --&gt; | true | N[分发结束&amp;处理完毕]</span><br><span class="line">M --&gt; O&#123;是否消耗&#125;</span><br><span class="line">O --&gt; | return false | Q(返回上级view的onTouchEvent)</span><br><span class="line">O --&gt; | view默认true | P[分发结束&amp;处理完毕]</span><br><span class="line">Q --&gt; I</span><br><span class="line">I --&gt; S&#123;是否消耗&#125;</span><br><span class="line">S --&gt; | ViewGroup默认return false | D</span><br><span class="line">S --&gt; | true | T[分发结束&amp;处理完毕]</span><br><span class="line">D --&gt; U&#123;是否消耗&#125;</span><br><span class="line">U --&gt; | true | W[分发结束&amp;处理完毕]</span><br><span class="line">U --&gt; | ViewGroup默认return false | V(Activity.onTouchEvent)</span><br><span class="line">V --&gt; X[分发结束&amp;处理完毕]</span><br></pre>

<h1 id="4-关于事件的总结（先上，后面有测试验证）"><a href="#4-关于事件的总结（先上，后面有测试验证）" class="headerlink" title="4.关于事件的总结（先上，后面有测试验证）"></a>4.关于事件的总结（先上，后面有测试验证）</h1><ol>
<li><p>同一事件序列：</p>
<pre><code> 指的是，从手指接触屏幕的那一刻开始，直至手指离开屏幕一刻结束。
 以ACTION_DOWN开始,以ACTION_UP结束，中间0或∞个ACTION_MOVE
</code></pre>
</li>
</ol>
<ol start="2">
<li>正常情况，一个事件序列只能被一个View拦截&amp;&amp;消耗。特殊情况，可以强行传递给其他View处理。</li>
</ol>
<ol start="3">
<li>一个事件序列，一旦被某个View拦截，那么只能由该View处理，且onInterceptTouchEvent不会再次调用，即不再多余询问是否拦截。</li>
</ol>
<ol start="4">
<li>当View开始处理事件，如果一开始的ACTION_DOWN事件未消耗，即【onTouchEvent()】返回了false，那么本次事件序列的后续事件【都不会】再交给该View处理,并且事件向上回流给父View的onTouchEvent()处理。</li>
</ol>
<ol start="5">
<li>如果View只消耗ACTION_DOWN事件，而不消耗其他触摸事件，则这个事件会消失；且 父View的onTouchEvent()不会被调用；且这些事件最终将交由Activity处理</li>
</ol>
<ol start="6">
<li>单纯的View控件，没有onInterceptTouchEvent()方法，事件分发到View，【onTouchEvent()】会被调用。「Activity也没有onInterceptTouchEvent()」</li>
</ol>
<ol start="7">
<li>ViewGroup比View多了一个onInterceptTouchEvent()，默认不拦截任何事件，即默认return false</li>
</ol>
<ol start="8">
<li>onTouchEvent()默认消耗事件 return true；特殊情况返回false：View被设置了clickable = = false &amp;&amp; longClickable = = false。(longClickable默认就是false)「Button默认clickable = = true,TextView默认clickable = = false」</li>
</ol>
<ol start="9">
<li>View的enable属性值，不影响onTouchEvent()的默认返回值true,clickable = = true || longClickable = = true 时 –&gt; onTouchEvent()就默认return true;</li>
</ol>
<ol start="10">
<li><p>View的enable属性值，会影响onTouchListener,enable = = false时，onTouchListener.onTouch()不会被执行</p>
</li>
<li><p>requestDisallowInterceptTouchEvent()可以在子View中干预【所有父View】的事件分发</p>
</li>
</ol>
<h1 id="5-代码测试-amp-验证"><a href="#5-代码测试-amp-验证" class="headerlink" title="5.代码测试&amp;验证"></a>5.代码测试&amp;验证</h1><p>先上一次正常的【点击事件】的事件分发+处理的log结果</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120162431_xtUUY0.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120162431_xtUUY0.png" class="lozad post-image">

<h2 id="5-1思路"><a href="#5-1思路" class="headerlink" title="5.1思路"></a>5.1思路</h2><ol>
<li>先自定义View,重写【dispatchTouchEvent】【onTouchEvent】两个方法，节点加上对应的log日志</li>
<li>自定义ViewGroupBBB重写【dispatchTouchEvent】【onInterceptTouchEvent】【onTouchEvent】三个方法，节点加上对应的log日志</li>
<li>同2.理，自定义ViewGroupAAA</li>
<li>Activity中重写【dispatchTouchEvent】【onTouchEvent】两个方法，节点加上对应的log日志</li>
<li>activity的布局文件摆放控件，ViewGroupAAA包含ViewGroupBBB,ViewGroupBBB包含ViewTestCCC</li>
<li>activity中，获取ViewTestCCC,设置其【setOnTouchListener】【setOnClickListener】，并在回调方法中增加log日志</li>
<li>修改关键节点方法的返回值，深入理解事件的分发&amp;处理机制</li>
</ol>
<h2 id="5-2先上代码"><a href="#5-2先上代码" class="headerlink" title="5.2先上代码"></a>5.2先上代码</h2><p>ViewTestCCC.java</p>
<pre class="highlight"><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ViewTestCCC</span> <span class="keyword">extends</span> <span class="title">View</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dispatchTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.dispatchTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.dispatchTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.onTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewTestCCC</span><span class="params">(Context context)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewTestCCC</span><span class="params">(Context context, <span class="meta">@Nullable</span> AttributeSet attrs)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewTestCCC</span><span class="params">(Context context, <span class="meta">@Nullable</span> AttributeSet attrs, <span class="keyword">int</span> defStyleAttr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewTestCCC</span><span class="params">(Context context, <span class="meta">@Nullable</span> AttributeSet attrs, <span class="keyword">int</span> defStyleAttr, <span class="keyword">int</span> defStyleRes)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr, defStyleRes);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre>

<p>ViewGroupBBB.java</p>
<pre class="highlight"><span class="line"><span class="keyword">public</span>  <span class="class"><span class="keyword">class</span> <span class="title">ViewGroupBBB</span> <span class="keyword">extends</span> <span class="title">RelativeLayout</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dispatchTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.dispatchTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.dispatchTouchEvent(ev);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onInterceptTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.onInterceptTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onInterceptTouchEvent(ev);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.onTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupBBB</span><span class="params">(Context context)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupBBB</span><span class="params">(Context context, AttributeSet attrs)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupBBB</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyleAttr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupBBB</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyleAttr, <span class="keyword">int</span> defStyleRes)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr, defStyleRes);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre>

<p>ViewGroupAAA.java</p>
<pre class="highlight"><span class="line"><span class="keyword">public</span>  <span class="class"><span class="keyword">class</span> <span class="title">ViewGroupAAA</span> <span class="keyword">extends</span> <span class="title">RelativeLayout</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dispatchTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupAAA.dispatchTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.dispatchTouchEvent(ev);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onInterceptTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupAAA.onInterceptTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onInterceptTouchEvent(ev);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupAAA.onTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupAAA</span><span class="params">(Context context)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupAAA</span><span class="params">(Context context, AttributeSet attrs)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupAAA</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyleAttr)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ViewGroupAAA</span><span class="params">(Context context, AttributeSet attrs, <span class="keyword">int</span> defStyleAttr, <span class="keyword">int</span> defStyleRes)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(context, attrs, defStyleAttr, defStyleRes);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre>

<p>Activity的布局文件.xml</p>
<pre class="highlight"><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span> <span class="attr">xmlns:android</span>=<span class="string">&quot;http://schemas.android.com/apk/res/android&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:app</span>=<span class="string">&quot;http://schemas.android.com/apk/res-auto&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:tools</span>=<span class="string">&quot;http://schemas.android.com/tools&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">tools:context</span>=<span class="string">&quot;.BaseSuperResourceActivity&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    &lt;com.cupster.base_super_resource.ViewGroupAAA</span><br><span class="line">        android:layout_width=&quot;500dp&quot;</span><br><span class="line">        android:layout_height=&quot;500dp&quot;</span><br><span class="line">        android:background=&quot;@android:color/holo_red_light&quot;</span><br><span class="line"></span><br><span class="line">        app:layout_constraintLeft_toLeftOf=&quot;parent&quot;</span><br><span class="line">        app:layout_constraintRight_toRightOf=&quot;parent&quot;</span><br><span class="line">        app:layout_constraintTop_toTopOf=&quot;parent&quot;</span><br><span class="line">        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;</span><br><span class="line">        &gt;</span><br><span class="line"></span><br><span class="line">        &lt;com.cupster.base_super_resource.ViewGroupBBB</span><br><span class="line">            android:layout_centerInParent=&quot;true&quot;</span><br><span class="line">            android:layout_width=&quot;300dp&quot;</span><br><span class="line">            android:layout_height=&quot;300dp&quot;</span><br><span class="line">            android:background=&quot;@android:color/holo_green_light&quot;</span><br><span class="line">            &gt;</span><br><span class="line">            &lt;com.cupster.base_super_resource.ViewTestCCC</span><br><span class="line">                android:id=&quot;@+id/view_ccc&quot;</span><br><span class="line">                android:layout_centerInParent=&quot;true&quot;</span><br><span class="line">                android:background=&quot;@android:color/holo_orange_light&quot;</span><br><span class="line">                android:layout_width=&quot;150dp&quot;</span><br><span class="line">                android:layout_height=&quot;150dp&quot;</span><br><span class="line">                /&gt;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">com.cupster.base_super_resource.ViewGroupBBB</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="tag">&lt;/<span class="name">com.cupster.base_super_resource.ViewGroupAAA</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span></span><br></pre>

<p>activity</p>
<pre class="highlight"><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseSuperResourceActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onCreate(savedInstanceState);</span><br><span class="line">        setContentView(R.layout.activity_base_super_resource);</span><br><span class="line"></span><br><span class="line">        View viewCCC = findViewById(R.id.view_ccc);</span><br><span class="line">        viewCCC.setOnTouchListener(<span class="keyword">new</span> View.OnTouchListener() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouch</span><span class="params">(View view, MotionEvent motionEvent)</span> </span>&#123;</span><br><span class="line">                Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.[[OnTouchListener]].onTouch() ====&quot;</span>);</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">        viewCCC.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View view)</span> </span>&#123;</span><br><span class="line">                Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.&lt;&lt;OnClickListener&gt;&gt;.onClick() ====&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">dispatchTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== Activity.dispatchTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.dispatchTouchEvent(ev);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== Activity.onTouchEvent ====&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">super</span>.onTouchEvent(event);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre>


<h2 id="5-3修改返回值，测试验证"><a href="#5-3修改返回值，测试验证" class="headerlink" title="5.3修改返回值，测试验证"></a>5.3修改返回值，测试验证</h2><p>正常点击事件的节点日志</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120162431_xtUUY0.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120162431_xtUUY0.png" class="lozad post-image">

<br/>
<br/>
<br/>
1.首先修改activity中【setOnTouchListener回调方法onTouch()】的返回值为true:即消耗事件


<pre class="highlight"><span class="line">viewCCC.setOnTouchListener(<span class="keyword">new</span> View.OnTouchListener() &#123;</span><br><span class="line">           <span class="meta">@Override</span></span><br><span class="line">           <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouch</span><span class="params">(View view, MotionEvent motionEvent)</span> </span>&#123;</span><br><span class="line">               Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.[[OnTouchListener]].onTouch() ====&quot;</span>);</span><br><span class="line">               <span class="keyword">return</span> <span class="keyword">true</span>;<span class="comment">//消费该事件，则不再继续分发流程</span></span><br><span class="line">           &#125;</span><br><span class="line">       &#125;);</span><br></pre>

<p>结果：不再调用【onTouchEvent()】,OnTouchListener优先级比【onTouchEvent()】高</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120164749_DyshE7.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120164749_DyshE7.png" class="lozad post-image">
<br/>
<br/>

<p>2.修改ViewTestCCC.java的【onTouchEvent()】的返回值为false:即 不处理</p>
<pre class="highlight"><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewTestCCC.onTouchEvent ====&quot;</span>);</span><br><span class="line"><span class="comment">//        return super.onTouchEvent(event);</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br></pre>

<p>结果：因为ViewGroupBBB、ViewGroupAAA的【onTouchEvent()】直接return super.onTouchEvent(),所以当View的【onTouchEvent()】未处理事件，事件将逐级回送给父view去处理，</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120170311_nk06Fm.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120170311_nk06Fm.png" class="lozad post-image">
<br/>
<br/>

<p>3.修改ViewGroupBBB.java的【onInterceptTouchEvent】拦截事件</p>
<pre class="highlight"><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onInterceptTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">    Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.onInterceptTouchEvent ====&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">&#125;</span><br></pre>

<p>结果：自身拦截了事件，则调用自身【onTouchEvent()】处理事件</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120170807_l36wkD.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120170807_l36wkD.png" class="lozad post-image">
<br/>
<br/>

<p>4.在3.的基础上，【onTouchEvent()】返回true：自身消费事件，则不再继续回送父view处理</p>
<pre class="highlight"><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onInterceptTouchEvent</span><span class="params">(MotionEvent ev)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.onInterceptTouchEvent ====&quot;</span>);</span><br><span class="line"><span class="comment">//        return super.onInterceptTouchEvent(ev);</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">onTouchEvent</span><span class="params">(MotionEvent event)</span> </span>&#123;</span><br><span class="line">        Log.e(<span class="string">&quot;touch_test&quot;</span>,<span class="string">&quot;===== ViewGroupBBB.onTouchEvent ====&quot;</span>);</span><br><span class="line"><span class="comment">//        return super.onTouchEvent(event);</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br></pre>

<p>结果：</p>
<img src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120171415_6qkqaI.png" / srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="https://gitee.com/cupster/picbed/raw/master/uPic/20210120171415_6qkqaI.png" class="lozad post-image">
<br/>
<br/>

<h1 id="6-至此，对View的事件分发-amp-处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。"><a href="#6-至此，对View的事件分发-amp-处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。" class="headerlink" title="6.至此，对View的事件分发&amp;处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。"></a>6.至此，对View的事件分发&amp;处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。</h1>
  </div>
  <div>
  
  <div class="post-note note-warning copyright" style="margin-top: 42px">
    <p><span style="font-weight: bold;">作者：</span><a target="_blank" rel="nofollow noopener noreferrer" href="http://example.com/about">Cupster</a></p>
    <p><span style="font-weight: bold;">文章链接：</span><a target="_blank" rel="nofollow noopener noreferrer" href="http://example.com/2019/07/17/014-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(9)%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91&amp;%E5%A4%84%E7%90%86%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/">http://example.com/2019/07/17/014-Android%E8%87%AA%E5%AE%9A%E4%B9%89View(9)%EF%BC%9A%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91&amp;%E5%A4%84%E7%90%86%E8%AF%A6%E8%A7%A3(%E5%9B%BE%E6%96%87)/</a></p>
    <p><span style="font-weight: bold;">版权声明：</span>本博客所有文章除特别声明外，均采用<a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0 协议</a>。转载请注明出处！</p>
  </div>
  
  </div>
</article>
<div class="nav">
  
  <div class="nav-item-prev">
    <a href="/2019/07/23/015-Android自定义View(10)：手势监听&amp;处理/" class="nav-link">
      <i class="iconfont icon-left nav-prev-icon"></i>
      <div>
        <div class="nav-label">上一篇</div>
        
        <div class="nav-title">015-Android自定义View(10)：手势监听&amp;处理 </div>
        
      </div>
    </a>
  </div>
  
  
  <div class="nav-item-next">
    <a href="/2019/07/15/013-Android自定义View(8)：绘制动画详解(图文)/" class="nav-link">
      <div>
        <div class="nav-label">下一篇</div>
        
        <div class="nav-title">013-Android自定义View(8)：绘制动画详解(图文) </div>
        
      </div>
      <i class="iconfont icon-right nav-next-icon"></i>
    </a>
  </div>
  
</div>

<div class="card card-content toc-card" id="mobiletoc">
  <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-1-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%EF%BC%9AdispatchTouchEvent-MotionEvent-event"><span class="toc-text">1.1 事件分发：dispatchTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-%E4%BA%8B%E4%BB%B6%E6%8B%A6%E6%88%AA%EF%BC%9AonInterceptTouchEvent-MotionEvent-event"><span class="toc-text">1.2 事件拦截：onInterceptTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-3-%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%EF%BC%9AonTouchEvent-MotionEvent-event"><span class="toc-text">1.3 事件处理：onTouchEvent(MotionEvent event)</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E7%89%B9%E6%AE%8A%E6%83%85%E5%86%B5"><span class="toc-text">2.特殊情况</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B%E5%9B%BE"><span class="toc-text">3.事件分发&amp;处理流程图</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#4-%E5%85%B3%E4%BA%8E%E4%BA%8B%E4%BB%B6%E7%9A%84%E6%80%BB%E7%BB%93%EF%BC%88%E5%85%88%E4%B8%8A%EF%BC%8C%E5%90%8E%E9%9D%A2%E6%9C%89%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81%EF%BC%89"><span class="toc-text">4.关于事件的总结（先上，后面有测试验证）</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#5-%E4%BB%A3%E7%A0%81%E6%B5%8B%E8%AF%95-amp-%E9%AA%8C%E8%AF%81"><span class="toc-text">5.代码测试&amp;验证</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#5-1%E6%80%9D%E8%B7%AF"><span class="toc-text">5.1思路</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-2%E5%85%88%E4%B8%8A%E4%BB%A3%E7%A0%81"><span class="toc-text">5.2先上代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-3%E4%BF%AE%E6%94%B9%E8%BF%94%E5%9B%9E%E5%80%BC%EF%BC%8C%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81"><span class="toc-text">5.3修改返回值，测试验证</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#6-%E8%87%B3%E6%AD%A4%EF%BC%8C%E5%AF%B9View%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%EF%BC%8C%E5%B7%B2%E7%BB%8F%E8%BE%BE%E5%88%B0%E5%AE%8C%E6%95%B4%E7%9A%84%E4%BA%86%E8%A7%A3%EF%BC%8C%E6%9B%B4%E5%A4%9A%E6%B7%B1%E5%85%A5%E6%AC%A2%E8%BF%8E%E5%85%B3%E6%B3%A8%E5%90%8E%E7%BB%AD%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E6%96%87%E7%AB%A0%E3%80%82"><span class="toc-text">6.至此，对View的事件分发&amp;处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。</span></a>
</div></main>
          <aside class="left-column">
            
            <div class="card card-author">
              
<img src="/img/ic_head.jpg" class="author-img">

<p class="author-name">Cupster</p>
<p class="author-description">深山磨柴斧，一鸣震江湖</p>
<div class="author-message">
  <a class="author-posts-count" href="/archives">
    <span>66</span>
    <span>文章</span>
  </a>
  <a class="author-categories-count" href="/categories">
    <span>5</span>
    <span>分类</span>
  </a>
  <a class="author-tags-count" href="/tags">
    <span>31</span>
    <span>标签</span>
  </a>
</div>

<div class="author-card-society">
  
    <div class="author-card-society-icon">
      <a target="_blank" rel="noopener" href="https://cupster.blog.csdn.net/">
        <i class="iconfont /img/ic_csdn.png society-icon"></i>
      </a>
    </div>
  
</div>

            </div>
            
            <div class="sticky-tablet">
  
  
  <article class="display-when-two-columns spacer">
    <div class="card card-content toc-card">
      <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-1-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%EF%BC%9AdispatchTouchEvent-MotionEvent-event"><span class="toc-text">1.1 事件分发：dispatchTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-%E4%BA%8B%E4%BB%B6%E6%8B%A6%E6%88%AA%EF%BC%9AonInterceptTouchEvent-MotionEvent-event"><span class="toc-text">1.2 事件拦截：onInterceptTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-3-%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%EF%BC%9AonTouchEvent-MotionEvent-event"><span class="toc-text">1.3 事件处理：onTouchEvent(MotionEvent event)</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E7%89%B9%E6%AE%8A%E6%83%85%E5%86%B5"><span class="toc-text">2.特殊情况</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B%E5%9B%BE"><span class="toc-text">3.事件分发&amp;处理流程图</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#4-%E5%85%B3%E4%BA%8E%E4%BA%8B%E4%BB%B6%E7%9A%84%E6%80%BB%E7%BB%93%EF%BC%88%E5%85%88%E4%B8%8A%EF%BC%8C%E5%90%8E%E9%9D%A2%E6%9C%89%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81%EF%BC%89"><span class="toc-text">4.关于事件的总结（先上，后面有测试验证）</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#5-%E4%BB%A3%E7%A0%81%E6%B5%8B%E8%AF%95-amp-%E9%AA%8C%E8%AF%81"><span class="toc-text">5.代码测试&amp;验证</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#5-1%E6%80%9D%E8%B7%AF"><span class="toc-text">5.1思路</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-2%E5%85%88%E4%B8%8A%E4%BB%A3%E7%A0%81"><span class="toc-text">5.2先上代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-3%E4%BF%AE%E6%94%B9%E8%BF%94%E5%9B%9E%E5%80%BC%EF%BC%8C%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81"><span class="toc-text">5.3修改返回值，测试验证</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#6-%E8%87%B3%E6%AD%A4%EF%BC%8C%E5%AF%B9View%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%EF%BC%8C%E5%B7%B2%E7%BB%8F%E8%BE%BE%E5%88%B0%E5%AE%8C%E6%95%B4%E7%9A%84%E4%BA%86%E8%A7%A3%EF%BC%8C%E6%9B%B4%E5%A4%9A%E6%B7%B1%E5%85%A5%E6%AC%A2%E8%BF%8E%E5%85%B3%E6%B3%A8%E5%90%8E%E7%BB%AD%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E6%96%87%E7%AB%A0%E3%80%82"><span class="toc-text">6.至此，对View的事件分发&amp;处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。</span></a>
    </div>
  </article>
  
  
  <article class="card card-content categories-widget">
    <div class="categories-card">
  <div class="categories-header"><i class="iconfont icon-fenlei" style="padding-right: 2px;"></i>分类</div>
  <div class="categories-list">
    
      <a href="/categories/Android/">
        <div class="categories-list-item">
          Android
          <span class="categories-list-item-badge">38</span>
        </div>
      </a>
    
      <a href="/categories/Linux/">
        <div class="categories-list-item">
          Linux
          <span class="categories-list-item-badge">6</span>
        </div>
      </a>
    
      <a href="/categories/Dev-Base/">
        <div class="categories-list-item">
          Dev-Base
          <span class="categories-list-item-badge">12</span>
        </div>
      </a>
    
      <a href="/categories/Kotlin/">
        <div class="categories-list-item">
          Kotlin
          <span class="categories-list-item-badge">9</span>
        </div>
      </a>
    
      <a href="/categories/自动化脚本/">
        <div class="categories-list-item">
          自动化脚本
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
  </div>
</div>
  </article>
  
  <article class="card card-content tags-widget">
    <div class="tags-card">
  <div class="tags-header"><i class="iconfont icon-biaoqian" style="padding-right: 2px;"></i>热门标签</div>
  <div class="tags-list">
    
    <a href="/tags/Android/" title="Android"><div class="tags-list-item">Android</div></a>
    
    <a href="/tags/Android自定义View/" title="Android自定义View"><div class="tags-list-item">Android自定义View</div></a>
    
    <a href="/tags/MacOS/" title="MacOS"><div class="tags-list-item">MacOS</div></a>
    
    <a href="/tags/Kotlin/" title="Kotlin"><div class="tags-list-item">Kotlin</div></a>
    
    <a href="/tags/Android持久化/" title="Android持久化"><div class="tags-list-item">Android持久化</div></a>
    
    <a href="/tags/CentOS/" title="CentOS"><div class="tags-list-item">CentOS</div></a>
    
    <a href="/tags/Linux/" title="Linux"><div class="tags-list-item">Linux</div></a>
    
    <a href="/tags/Android事件/" title="Android事件"><div class="tags-list-item">Android事件</div></a>
    
    <a href="/tags/Android基础/" title="Android基础"><div class="tags-list-item">Android基础</div></a>
    
    <a href="/tags/Android手势/" title="Android手势"><div class="tags-list-item">Android手势</div></a>
    
    <a href="/tags/Scrcpy/" title="Scrcpy"><div class="tags-list-item">Scrcpy</div></a>
    
    <a href="/tags/Android动画/" title="Android动画"><div class="tags-list-item">Android动画</div></a>
    
    <a href="/tags/Git/" title="Git"><div class="tags-list-item">Git</div></a>
    
    <a href="/tags/Java/" title="Java"><div class="tags-list-item">Java</div></a>
    
    <a href="/tags/Docker/" title="Docker"><div class="tags-list-item">Docker</div></a>
    
    <a href="/tags/Android-Dialog/" title="Android Dialog"><div class="tags-list-item">Android Dialog</div></a>
    
  </div>
</div>
  </article>
  
  
</div>
          </aside>
          <aside class="right-column">
            <div class="sticky-widescreen">
  
  
  <article class="card card-content toc-card">
    <div class="toc-header"><i class="iconfont icon-menu" style="padding-right: 2px;"></i>目录</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-1-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%EF%BC%9AdispatchTouchEvent-MotionEvent-event"><span class="toc-text">1.1 事件分发：dispatchTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-%E4%BA%8B%E4%BB%B6%E6%8B%A6%E6%88%AA%EF%BC%9AonInterceptTouchEvent-MotionEvent-event"><span class="toc-text">1.2 事件拦截：onInterceptTouchEvent(MotionEvent event)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-3-%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%EF%BC%9AonTouchEvent-MotionEvent-event"><span class="toc-text">1.3 事件处理：onTouchEvent(MotionEvent event)</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E7%89%B9%E6%AE%8A%E6%83%85%E5%86%B5"><span class="toc-text">2.特殊情况</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#3-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B%E5%9B%BE"><span class="toc-text">3.事件分发&amp;处理流程图</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#4-%E5%85%B3%E4%BA%8E%E4%BA%8B%E4%BB%B6%E7%9A%84%E6%80%BB%E7%BB%93%EF%BC%88%E5%85%88%E4%B8%8A%EF%BC%8C%E5%90%8E%E9%9D%A2%E6%9C%89%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81%EF%BC%89"><span class="toc-text">4.关于事件的总结（先上，后面有测试验证）</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#5-%E4%BB%A3%E7%A0%81%E6%B5%8B%E8%AF%95-amp-%E9%AA%8C%E8%AF%81"><span class="toc-text">5.代码测试&amp;验证</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#5-1%E6%80%9D%E8%B7%AF"><span class="toc-text">5.1思路</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-2%E5%85%88%E4%B8%8A%E4%BB%A3%E7%A0%81"><span class="toc-text">5.2先上代码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-3%E4%BF%AE%E6%94%B9%E8%BF%94%E5%9B%9E%E5%80%BC%EF%BC%8C%E6%B5%8B%E8%AF%95%E9%AA%8C%E8%AF%81"><span class="toc-text">5.3修改返回值，测试验证</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#6-%E8%87%B3%E6%AD%A4%EF%BC%8C%E5%AF%B9View%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91-amp-%E5%A4%84%E7%90%86%EF%BC%8C%E5%B7%B2%E7%BB%8F%E8%BE%BE%E5%88%B0%E5%AE%8C%E6%95%B4%E7%9A%84%E4%BA%86%E8%A7%A3%EF%BC%8C%E6%9B%B4%E5%A4%9A%E6%B7%B1%E5%85%A5%E6%AC%A2%E8%BF%8E%E5%85%B3%E6%B3%A8%E5%90%8E%E7%BB%AD%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E6%96%87%E7%AB%A0%E3%80%82"><span class="toc-text">6.至此，对View的事件分发&amp;处理，已经达到完整的了解，更多深入欢迎关注后续源码分析文章。</span></a>
  </article>
  
  
  <article class="card card-content">
    <div class="recent-posts-card">
  <div class="recent-posts-header"><i class="iconfont icon-wenzhang_huaban" style="padding-right: 2px;"></i>最近文章</div>
  <div class="recent-posts-list">
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-03-02</div>
        <a href="/2021/03/02/Git commit规范/"><div class="recent-posts-item-content">Git commit规范</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-02-16</div>
        <a href="/2021/02/16/AutoJS一文精通AutoJS脚本教程详解/"><div class="recent-posts-item-content">AutoJS一文精通AutoJS脚本教程详解</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-01-21</div>
        <a href="/2021/01/21/架构师进阶：注解Annotation全解/"><div class="recent-posts-item-content">架构师进阶：注解Annotation全解</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2021-01-06</div>
        <a href="/2021/01/06/ConstraintLayout详解/"><div class="recent-posts-item-content">ConstraintLayout详解</div></a>
      </div>
    
  </div>
</div>
  </article>
  
  
</div>
          </aside>
        </div>
      </div>
    </div>
  </div>
  
  <footer class="footer">
  <div class="footer-container">
    <div>
      <div class="footer-dsc">
        <span>Copyright ©
          
          2020 -
          
          2021
        </span>
        &nbsp;
        <a href="/" class="footer-link">不负明天 </a>
      </div>
    </div>

    
    <div class="footer-dsc">
      
      Powered by
      <a href="https://hexo.io/" class="footer-link" target="_blank" rel="nofollow noopener noreferrer">&nbsp;Hexo </a>
      
      
      <span>&nbsp;|&nbsp;</span>
      
      
      Theme -
      <a href="https://github.com/theme-kaze" class="footer-link" target="_blank"
        rel="nofollow noopener noreferrer">&nbsp;Kaze</a>
      
    </div>
    
    
    
    
      <div class="footer-dsc">
        
        本站总访问量686<span id="busuanzi_value_site_pv"></span>次
        
        
        <span>&nbsp;|&nbsp;</span>
        
        
        本站总访客数219<span id="busuanzi_value_site_uv"></span>次
        
      </div>
      
    
</footer>
  <a role="button" id="scrollbutton" class="basebutton"  aria-label="回到顶部">
  <i class="iconfont icon-arrowleft button-icon"></i>
</a>
<a role="button" id="menubutton" class="basebutton">
  <i class="iconfont icon-menu button-icon"></i>
</a>
<a role="button" id="popbutton" class="basebutton" aria-label="控制中心">
  <i class="iconfont icon-expand button-icon"></i>
</a>
<a role="button" id="darkbutton" class="basebutton darkwidget" aria-label="夜色模式">
  <i class="iconfont icon-weather button-icon"></i>
</a>
<a role="button" id="searchbutton" class="basebutton searchwidget" aria-label="搜索">
  <i class="iconfont icon-search button-icon"></i>
</a>

  
  
  
  <script>
  var addImgLayout = function () {
    var img = document.querySelectorAll('.post-content img');
    var i;
    for (i = 0; i < img.length; i++) {
      var wrapper = document.createElement('a');
      wrapper.setAttribute('href', img[i].getAttribute('data-src'));
      wrapper.setAttribute('aria-label', 'illustration');
      wrapper.style.cssText = 'width: 100%; display: flex; justify-content: center;';
      if (img[i].alt) wrapper.dataset.caption = img[i].alt;
      wrapper.dataset.nolink = true;
      img[i].before(wrapper);
      wrapper.append(img[i]);
      var divWrap = document.createElement('div');
      divWrap.classList.add('gallery');
      wrapper.before(divWrap);
      divWrap.append(wrapper);
    }
    baguetteBox.run('.gallery');
  }
</script>
<script>loadScript("/js/lib/lightbox/baguetteBox.min.js", addImgLayout)</script>
  
  
  
<script src="/js/main.js"></script>

  
  <script>loadScript("/js/lib/busuanzi.min.js")</script>
  
  
  <script>
    var addLazyload = function () {
      var observer = lozad('.lozad', {
        load: function (el) {
          el.srcset = el.getAttribute('data-src');
        },
        loaded: function (el) {
          el.classList.add('loaded');
        }
      });
      observer.observe();
    }
  </script>
  <script>loadScript("/js/lib/lozad.min.js", addLazyload)</script>
  
  
</body>

</html>